package com.yehuo.app.service.impl;

import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yehuo.app.entity.Dict;
import com.yehuo.app.entity.Wallet;
import com.yehuo.app.entity.Withdrawal;
import com.yehuo.app.entity.dto.SelectWithdrawalDto;
import com.yehuo.app.mapper.DictMapper;
import com.yehuo.app.mapper.UserMapper;
import com.yehuo.app.mapper.WalletMapper;
import com.yehuo.app.mapper.WthdrawalMapper;
import com.yehuo.app.model.R;
import com.yehuo.app.model.Result;
import com.yehuo.app.service.WthdrawalService;
import com.yehuo.app.util.WXPayUtil;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import java.io.*;
import java.security.KeyStore;
import java.util.*;

@Service
public class WthdrawalServiceImpl implements WthdrawalService {

    @Resource
    private WthdrawalMapper wthdrawalMapper;
    @Resource
    private UserMapper userMapper;
    @Resource
    private WalletMapper walletMapper;
    @Resource
    private DictMapper dictMapper;
    private String MCHID;
    private String MCHAPPID;
    private String keyWX;
    private  String withdrawApi;

    /**
     * 提现列表
     * @param selectWithdrawalDto
     * @return
     */
    public R selectWithdrawals(SelectWithdrawalDto selectWithdrawalDto){
        //获取查询条件
        Map<String, Object> conditions = selectWithdrawalDto.getCondition();
        PageHelper.startPage(selectWithdrawalDto.getPage(),selectWithdrawalDto.getLimit());
        //查询
        List<Map<String, Object>> orderList = wthdrawalMapper.selectOrdersByConditions(conditions);
        PageInfo<Map<String,Object>> pageInfo = new PageInfo<>(orderList);
        R<Map<String,Object>> result = new R<>((int) pageInfo.getTotal(), pageInfo.getList());
        return result;
    }

    /**
     * 获取自动自动提现状态
     * @return
     */
    @Override
    public Result selectAutoCode() {
        Dict dict = dictMapper.selectById(1);
        Result result = new Result();
        result.setCode(200);
        result.setResult(dict.getValue());
        return result;
    }

    /**
     *
     * @param status
     * @return
     */
    @Override
    public Result updateAutoWithdrawal(String status) {
        Dict dict = dictMapper.selectById(1);
        dict.setValue(status);
        dictMapper.updateById(dict);
        Result result = new Result();
        result.setCode(200);
        result.setMsg("更新成功");
        return result;
    }

    /**
     * 审核提现订单
     * @param wthdrawalId
     * @return
     */
    @Override
    public Result checkWithdrawal(String wthdrawalId, Integer type) {
        Withdrawal wthdrawal = wthdrawalMapper.selectById(wthdrawalId);
        Result result = new Result();
        if (type == 2){//拒绝提现
            returnMoney(wthdrawal);
            result.setMsg("拒绝提现");
            result.setCode(200);
            wthdrawal.setStatus(2);
        }else {//提现
            Map<String, String> map = new HashMap<>();
            Map<String, String> data = new HashMap<>();
            data.put("mch_appid", MCHAPPID);
            data.put("mchid", MCHID);
            data.put("nonce_str", UUID.randomUUID().toString().replaceAll("-", ""));
            data.put("partner_trade_no", UUID.randomUUID().toString().replaceAll("-", ""));
            data.put("openid", wthdrawal.getReceiverAccount());
            data.put("check_name", "NO_CHECK");
            data.put("amount", getWXMoney(wthdrawal.getAmount()));
            data.put("desc", "提现");
            try {
                //生成证书
                String signMap = WXPayUtil.generateSignature(data, keyWX, WXPayUtil.SignType.MD5);
                //发起请求支付接口
                String respose = ssl(withdrawApi, signMap);
                map = WXPayUtil.xmlToMap(respose);
            } catch (Exception e) {
                e.printStackTrace();
                result.setMsg("系统异常");
                result.setCode(500);
            }
            //提现成功
            if ("SUCCESS".equals(map.get("result_code")) && map.get("err_code") == null) {
                result.setMsg("提现成功");
                result.setCode(200);
                wthdrawal.setStatus(3);
            } else {
                //提现失败
                wthdrawal.setStatus(4);
                //退还余额
                returnMoney(wthdrawal);
                result.setMsg("提现失败");
                result.setCode(200);
            }
        }
        wthdrawal.setUpateTime(new Date());
        wthdrawalMapper.updateById(wthdrawal);
        return result;
    }

    /**
     * 退还金额
     * @param wthdrawal
     */
    public void returnMoney(Withdrawal wthdrawal){
        QueryWrapper<Wallet> qw = new QueryWrapper<>();
        qw.eq("user_id",wthdrawal.getUserId());
        Wallet wallet = walletMapper.selectOne(qw);
        wallet.setAmount((stringAdd(wallet.getAmount(),wthdrawal.getAmount())));
        wallet.setUpdateTime(new Date());
        walletMapper.updateById(wallet);
    }
    /**
     * 发请求
     * @param url
     * @param data
     * @return
     */
    private  String ssl(String url,String data){
        //获取证书路径
        String path = "";
        System.out.println(path);

        StringBuffer message = new StringBuffer();
        try {
            KeyStore keyStore  = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(new File(path));
            keyStore.load(instream, MCHID.toCharArray());
            instream.close();
            // Trust own CA and all self-signed certs
            SSLContext sslcontext = SSLContexts.custom()
                    .loadKeyMaterial(keyStore, MCHID.toCharArray())
                    .build();
            // Allow TLSv1 protocol only
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                    sslcontext,
                    new String[] { "TLSv1" },
                    null,
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);
            CloseableHttpClient httpclient = HttpClients.custom()
                    .setSSLSocketFactory(sslsf)
                    .build();
            HttpPost httpost = new HttpPost(url);

            httpost.addHeader("Connection", "keep-alive");
            httpost.addHeader("Accept", "*/*");
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
            httpost.addHeader("Host", "api.mch.weixin.qq.com");
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");
            httpost.addHeader("Cache-Control", "max-age=0");
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");
            httpost.setEntity(new StringEntity(data, "UTF-8"));
            //System.out.println("executing request" + httpost.getRequestLine());

            CloseableHttpResponse response = httpclient.execute(httpost);
            try {
                HttpEntity entity = response.getEntity();

                //System.out.println("----------------------------------------");
                //System.out.println(response.getStatusLine());
                if (entity != null) {
                    //System.out.println("Response content length: " + entity.getContentLength());
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(),"UTF-8"));
                    String text;
                    while ((text = bufferedReader.readLine()) != null) {
                        message.append(text);
                    }
                }
                EntityUtils.consume(entity);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                response.close();
            }
        } catch (Exception e1) {
            e1.printStackTrace();
        }

        return message.toString();
    }

    /**
     * 生成订单金额
     * @param money
     * @return
     */
    public String getWXMoney(String money){
        if(StringUtils.isEmpty(money)){
            money = "0";
        }
        return String.valueOf(Double.parseDouble(money)*100);
    }

    /**
     * 字符串相加
     * @param a
     * @param b
     * @return
     */
    public String stringAdd(String a, String b){
        if(StringUtils.isEmpty(a)){
            a = "0";
        }
        if(StringUtils.isEmpty(b)){
            b = "0";
        }
        return String.valueOf(Double.parseDouble(a) + Double.parseDouble(b));
    }
}
